#ifndef _NE_PLANE_H_
#define _NE_PLANE_H_

#include <mathematics/Vector3.h>

namespace ne
{
    class AABB;
    class Sphere;

    class NEAPI Plane
    {
        public:
            enum Side
            {
                NO_SIDE = 0x00,
                POSITIVE_SIDE = 0x01,
                NEGATIVE_SIDE = 0x02,
                BOTH_SIDE = 0x03
            };

        public:
            Plane();

            Plane(const Plane &p);

            Plane(const Vector3 &vNormal, const real rD);

            Plane(const Vector3 &vNormal, const Vector3 &point);

            Plane(const Vector3 &point0, const Vector3 &point1, const Vector3 &point2);

            Plane(const real a, const real b, const real c, const real rD);

            void redefine(const Vector3 &normal, const real d);

            void redefine(const Vector3 &normal, const Vector3 &point);

            void redefine(const Vector3 &point0, const Vector3 &point1, const Vector3 &point2);

            void redefine(const real a, const real b, const real c, const real d);

            real normalize();

            real getDistance(const Vector3 &point) const;

            Side getSide(const Vector3 &point) const;

            Side getSide(const AABB &a) const;

            Side getSide(const Plane &p) const;

            Side getSide(const Sphere &s) const;

            // Get side of Box
            Side getSide(const Vector3 &center, const Vector3 &halfSize) const;

            Vector3 projectVector(const Vector3 &point) const;

            Vector3 reflectVector(const Vector3 &point) const;

            Plane& operator = (const Plane &p);

            bool operator == (const Plane &p) const;

            bool operator != (const Plane &p) const;

            // Function for writing to a stream.
            NEAPI friend std::ostream& operator << (std::ostream &o, const Plane &p);

            inline ~Plane() {}

        public:
            Vector3 normal;
            real d;
    };
}

#endif
